home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!bbn.com!rsalz
- From: rsalz@uunet.uu.net (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v18i078: MIT Athena delete/undelete programs, Part06/06
- Message-ID: <1638@fig.bbn.com>
- Date: 29 Mar 89 04:33:55 GMT
- Lines: 649
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Jonathan I. Kamens <jik@PIT-MANAGER.MIT.EDU>
- Posting-number: Volume 18, Issue 78
- Archive-name: undel/part06
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 6 (of 6)."
- # Contents: directories.c
- # Wrapped by jik@pit-manager on Mon Mar 27 12:16:56 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'directories.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'directories.c'\"
- else
- echo shar: Extracting \"'directories.c'\" \(12581 characters\)
- sed "s/^X//" >'directories.c' <<'END_OF_FILE'
- X/*
- X * $Source: /mit/jik/src/delete/RCS/directories.c,v $
- X * $Author: jik $
- X *
- X * This program is part of a package including delete, undelete,
- X * lsdel, expunge and purge. The software suite is meant as a
- X * replacement for rm which allows for file recovery.
- X *
- X * Copyright (c) 1989 by the Massachusetts Institute of Technology.
- X * For copying and distribution information, see the file "mit-copyright.h."
- X */
- X
- X#if !defined(lint) && !defined(SABER)
- X static char rcsid_directories_c[] = "$Header: directories.c,v 1.12 89/03/27 12:06:16 jik Exp $";
- X#endif
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/param.h>
- X#include <sys/dir.h>
- X#include <strings.h>
- X#include "directories.h"
- X#include "util.h"
- X#include "mit-copyright.h"
- X
- Xextern char *malloc(), *realloc();
- Xextern char *whoami;
- X
- Xstatic filerec root_tree;
- Xstatic filerec cwd_tree;
- Xstatic char *error_buf;
- X
- X /* these are not static because external routines need to be able to */
- X /* access them. */
- Xlong current_time;
- X
- X
- Xstatic filerec default_cwd = {
- X "",
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X False,
- X False,
- X {0}
- X};
- X
- Xstatic filerec default_root = {
- X "/",
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X False,
- X False,
- X {0}
- X};
- X
- Xstatic filerec default_directory = {
- X "",
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X False,
- X False,
- X {0}
- X};
- X
- Xstatic filerec default_file = {
- X "",
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X (filerec *) NULL,
- X False,
- X False,
- X {0}
- X};
- X
- X
- Xfilerec *get_root_tree()
- X{
- X return(&root_tree);
- X}
- X
- X
- X
- Xfilerec *get_cwd_tree()
- X{
- X return(&cwd_tree);
- X}
- X
- X
- Xinitialize_tree()
- X{
- X int status;
- X
- X root_tree = default_root;
- X cwd_tree = default_cwd;
- X
- X current_time = time(0);
- X error_buf = (char *) malloc(MAXPATHLEN + strlen(whoami) + 5);
- X if (! error_buf) {
- X return(1);
- X }
- X status = get_specs("", &cwd_tree.specs, FOLLOW_LINKS);
- X if (! status)
- X status = get_specs("/", &root_tree.specs, FOLLOW_LINKS);
- X return(status);
- X}
- X
- X
- Xfilerec *add_path_to_tree(path)
- Xchar *path;
- X{
- X filerec *parent, *leaf;
- X char next_name[MAXNAMLEN];
- X char lpath[MAXPATHLEN], built_path[MAXPATHLEN], *ptr;
- X struct stat specs;
- X
- X if (get_specs(path, &specs, DONT_FOLLOW_LINKS))
- X return((filerec *) NULL);
- X ptr = strcpy(lpath, path); /* we don't want to damage the user's string */
- X if (*ptr == '/') {
- X parent = &root_tree;
- X ptr++;
- X strcpy(built_path, "/");
- X }
- X else if (! strncmp(ptr, "./", 2)) {
- X parent = &cwd_tree;
- X ptr += 2;
- X *built_path = '\0';
- X }
- X else {
- X parent = &cwd_tree;
- X *built_path = '\0';
- X }
- X
- X strcpy(next_name, firstpart(ptr, ptr));
- X while (*ptr) {
- X strcat(built_path, next_name);
- X parent = add_directory_to_parent(parent, next_name, False);
- X if (! parent)
- X return ((filerec *) NULL);
- X strcpy(next_name, firstpart(ptr, ptr));
- X if (get_specs(built_path, &parent->specs, FOLLOW_LINKS))
- X return((filerec *) NULL);
- X strcat(built_path, "/");
- X }
- X if ((specs.st_mode & S_IFMT) == S_IFDIR)
- X leaf = add_directory_to_parent(parent, next_name, True);
- X else
- X leaf = add_file_to_parent(parent, next_name, True);
- X
- X if (! leaf)
- X return ((filerec *) NULL);
- X leaf->specs = specs;
- X
- X return(leaf);
- X}
- X
- X
- X
- X
- Xget_specs(path, specs, follow)
- Xchar *path;
- Xstruct stat *specs;
- Xint follow;
- X{
- X int status;
- X
- X if (strlen(path)) if ((path[strlen(path) - 1] == '/') &&
- X (strlen(path) != 1))
- X path[strlen(path) - 1] = '\0';
- X if (follow == FOLLOW_LINKS)
- X status = stat(path, specs);
- X else
- X status = lstat(path, specs);
- X
- X if (status)
- X return(1);
- X else
- X return(0);
- X}
- X
- X
- X
- Xfilerec *next_leaf(leaf)
- Xfilerec *leaf;
- X{
- X filerec *new;
- X
- X if ((leaf->specs.st_mode & S_IFMT) == S_IFDIR) {
- X new = first_in_directory(leaf);
- X if (new)
- X return(new);
- X new = next_directory(leaf);
- X return(new);
- X }
- X else {
- X new = next_in_directory(leaf);
- X return(new);
- X }
- X}
- X
- X
- Xfilerec *next_specified_leaf(leaf)
- Xfilerec *leaf;
- X{
- X while (leaf = next_leaf(leaf))
- X if (leaf->specified)
- X return(leaf);
- X return((filerec *) NULL);
- X}
- X
- X
- Xfilerec *next_directory(leaf)
- Xfilerec *leaf;
- X{
- X filerec *ret;
- X if ((leaf->specs.st_mode & S_IFMT) != S_IFDIR)
- X leaf = leaf->parent;
- X if (leaf)
- X ret = leaf->next;
- X else
- X ret = (filerec *) NULL;
- X if (ret) if (ret->freed)
- X ret = next_directory(ret);
- X return(ret);
- X}
- X
- X
- Xfilerec *next_specified_directory(leaf)
- Xfilerec *leaf;
- X{
- X while (leaf = next_directory(leaf))
- X if (leaf->specified)
- X return(leaf);
- X return ((filerec *) NULL);
- X}
- X
- X
- X
- Xfilerec *next_in_directory(leaf)
- Xfilerec *leaf;
- X{
- X filerec *ret;
- X
- X if (leaf->next)
- X ret = leaf->next;
- X else if (((leaf->specs.st_mode & S_IFMT) != S_IFDIR) && leaf->parent)
- X ret = leaf->parent->dirs;
- X else
- X ret = (filerec *) NULL;
- X if (ret) if (ret->freed)
- X ret = next_in_directory(ret);
- X return (ret);
- X}
- X
- X
- X
- X
- Xfilerec *next_specified_in_directory(leaf)
- Xfilerec *leaf;
- X{
- X while (leaf = next_in_directory(leaf))
- X if (leaf->specified)
- X return(leaf);
- X return ((filerec *) NULL);
- X}
- X
- X
- X
- Xfilerec *first_in_directory(leaf)
- Xfilerec *leaf;
- X{
- X filerec *ret;
- X
- X if ((leaf->specs.st_mode & S_IFMT) != S_IFDIR)
- X ret = (filerec *) NULL;
- X else if (leaf->files)
- X ret = leaf->files;
- X else if (leaf->dirs)
- X ret = leaf->dirs;
- X else
- X ret = (filerec *) NULL;
- X if (ret) if (ret->freed)
- X ret = next_in_directory(ret);
- X return(ret);
- X}
- X
- X
- Xfilerec *first_specified_in_directory(leaf)
- Xfilerec *leaf;
- X{
- X leaf = first_in_directory(leaf);
- X if (! leaf)
- X return((filerec *) NULL);
- X
- X if (leaf->specified)
- X return(leaf);
- X else
- X leaf = next_specified_in_directory(leaf);
- X return (leaf);
- X}
- X
- X
- Xprint_paths_from(leaf)
- Xfilerec *leaf;
- X{
- X char buf[MAXPATHLEN];
- X
- X printf("%s\n", get_leaf_path(leaf, buf));
- X if (leaf->dirs)
- X print_paths_from(leaf->dirs);
- X if (leaf->files)
- X print_paths_from(leaf->files);
- X if (leaf->next)
- X print_paths_from(leaf->next);
- X return(0);
- X}
- X
- X
- Xprint_specified_paths_from(leaf)
- Xfilerec *leaf;
- X{
- X char buf[MAXPATHLEN];
- X
- X if (leaf->specified)
- X printf("%s\n", get_leaf_path(leaf, buf));
- X if (leaf->dirs)
- X print_specified_paths_from(leaf->dirs);
- X if (leaf->files)
- X print_specified_paths_from(leaf->files);
- X if (leaf->next)
- X print_specified_paths_from(leaf->next);
- X return(0);
- X}
- X
- X
- Xfilerec *add_file_to_parent(parent, name, specified)
- Xfilerec *parent;
- Xchar *name;
- XBoolean specified;
- X{
- X filerec *files, *last = (filerec *) NULL;
- X
- X files = parent->files;
- X while (files) {
- X if (! strcmp(files->name, name))
- X break;
- X last = files;
- X files = files->next;
- X }
- X if (files) {
- X files->specified = (files->specified || specified);
- X return(files);
- X }
- X if (last) {
- X last->next = (filerec *) malloc(sizeof(filerec));
- X if (! last->next)
- X return((filerec *) NULL);
- X *last->next = default_file;
- X last->next->previous = last;
- X last->next->parent = parent;
- X last = last->next;
- X }
- X else {
- X parent->files = (filerec *) malloc(sizeof(filerec));
- X if (! parent->files)
- X return((filerec *) NULL);
- X *parent->files = default_file;
- X parent->files->parent = parent;
- X parent->files->previous = (filerec *) NULL;
- X last = parent->files;
- X }
- X strcpy(last->name, name);
- X last->specified = specified;
- X return(last);
- X}
- X
- X
- X
- X
- X
- Xfilerec *add_directory_to_parent(parent, name, specified)
- Xfilerec *parent;
- Xchar *name;
- XBoolean specified;
- X{
- X filerec *directories, *last = (filerec *) NULL;
- X
- X directories = parent->dirs;
- X while (directories) {
- X if (! strcmp(directories->name, name))
- X break;
- X last = directories;
- X directories = directories->next;
- X }
- X if (directories) {
- X directories->specified = (directories->specified || specified);
- X return(directories);
- X }
- X if (last) {
- X last->next = (filerec *) malloc(sizeof(filerec));
- X if (! last->next)
- X return((filerec *) NULL);
- X *last->next = default_directory;
- X last->next->previous = last;
- X last->next->parent = parent;
- X last = last->next;
- X }
- X else {
- X parent->dirs = (filerec *) malloc(sizeof(filerec));
- X if (! parent->dirs)
- X return((filerec *) NULL);
- X *parent->dirs = default_directory;
- X parent->dirs->parent = parent;
- X parent->dirs->previous = (filerec *) NULL;
- X last = parent->dirs;
- X }
- X strcpy(last->name, name);
- X last->specified = specified;
- X return(last);
- X}
- X
- X
- X
- X
- X
- Xfree_leaf(leaf)
- Xfilerec *leaf;
- X{
- X leaf->freed = True;
- X if (! (leaf->dirs || leaf->files)) {
- X if (leaf->previous)
- X leaf->previous->next = leaf->next;
- X if (leaf->next)
- X leaf->next->previous = leaf->previous;
- X if (leaf->parent) {
- X if ((leaf->specs.st_mode & S_IFMT) == S_IFDIR) {
- X if (leaf->parent->dirs == leaf) {
- X leaf->parent->dirs = leaf->next;
- X if (leaf->parent->freed)
- X free_leaf(leaf->parent);
- X }
- X }
- X else {
- X if (leaf->parent->files == leaf) {
- X leaf->parent->files = leaf->next;
- X if (leaf->parent->freed)
- X free_leaf(leaf->parent);
- X }
- X }
- X free(leaf);
- X }
- X }
- X return(0);
- X}
- X
- X
- X
- Xfilerec *find_child(directory, name)
- Xfilerec *directory;
- Xchar *name;
- X{
- X filerec *ptr;
- X
- X if ((directory->specs.st_mode & S_IFMT) != S_IFDIR)
- X return ((filerec *) NULL);
- X ptr = directory->dirs;
- X while (ptr)
- X if (strcmp(ptr->name, name))
- X ptr = ptr->next;
- X else
- X break;
- X if (ptr)
- X return (ptr);
- X ptr = directory->files;
- X while (ptr)
- X if (strcmp(ptr->name, name))
- X ptr = ptr->next;
- X else
- X break;
- X if (ptr)
- X return (ptr);
- X return ((filerec *) NULL);
- X}
- X
- X
- X
- X
- X
- Xchange_path(old_path, new_path)
- Xchar *old_path, *new_path;
- X{
- X char next_old[MAXNAMLEN], next_new[MAXNAMLEN];
- X char rest_old[MAXPATHLEN], rest_new[MAXPATHLEN];
- X
- X filerec *current;
- X
- X if (*old_path == '/') {
- X current = &root_tree;
- X old_path++;
- X new_path++;
- X }
- X else if (! strncmp(old_path, "./", 2)) {
- X current = &cwd_tree;
- X old_path += 2;
- X new_path += 2;
- X }
- X else
- X current = &cwd_tree;
- X
- X strcpy(next_old, firstpart(old_path, rest_old));
- X strcpy(next_new, firstpart(new_path, rest_new));
- X while (*next_old && *next_new) {
- X current = find_child(current, next_old);
- X if (current)
- X strcpy(current->name, next_new);
- X else
- X return(1);
- X strcpy(next_old, firstpart(rest_old, rest_old));
- X strcpy(next_new, firstpart(rest_new, rest_new));
- X }
- X if (! (*next_old || *next_new))
- X return(0);
- X else
- X return(1);
- X}
- X
- X
- Xchar *get_leaf_path(leaf, leaf_buf)
- Xfilerec *leaf;
- Xchar leaf_buf[]; /* RETURN */
- X{
- X char *name_ptr;
- X
- X name_ptr = malloc(1);
- X if (! name_ptr) {
- X *leaf_buf = '\0';
- X return(leaf_buf);
- X }
- X *name_ptr = '\0';
- X do {
- X name_ptr = realloc(name_ptr, strlen(leaf->name) +
- X strlen(name_ptr) + 2);
- X if (! name_ptr) {
- X *leaf_buf = '\0';
- X return(leaf_buf);
- X }
- X strcpy(leaf_buf, name_ptr);
- X *name_ptr = '\0';
- X if (leaf->parent) if (leaf->parent->parent)
- X strcat(name_ptr, "/");
- X strcat(name_ptr, leaf->name);
- X strcat(name_ptr, leaf_buf);
- X leaf = leaf->parent;
- X } while (leaf);
- X strcpy(leaf_buf, name_ptr);
- X return(leaf_buf);
- X}
- X
- X
- X
- X
- X
- Xchar **accumulate_names(leaf, strings, num)
- Xfilerec *leaf;
- Xchar **strings;
- Xint *num;
- X{
- X char newname[MAXPATHLEN];
- X
- X if (leaf->specified) {
- X *num += 1;
- X strings = (char **) realloc(strings, sizeof(char *) * (*num));
- X if (! strings) {
- X perror(sprintf(error_buf, "%s: accumulate_names", whoami));
- X exit(1);
- X }
- X convert_to_user_name(get_leaf_path(leaf, newname), newname);
- X strings[*num - 1] = malloc(strlen(newname) + 1);
- X if (! strings[*num - 1]) {
- X perror(sprintf(error_buf, "%s: accumulate_names", whoami));
- X exit(1);
- X }
- X strcpy(strings[*num - 1], newname);
- X }
- X if (leaf->files)
- X strings = accumulate_names(leaf->files, strings, num);
- X if (leaf->dirs)
- X strings = accumulate_names(leaf->dirs, strings, num);
- X if (leaf->next)
- X strings = accumulate_names(leaf->next, strings, num);
- X
- X return(strings);
- X}
- END_OF_FILE
- if test 12581 -ne `wc -c <'directories.c'`; then
- echo shar: \"'directories.c'\" unpacked with wrong size!
- fi
- # end of 'directories.c'
- fi
- echo shar: End of archive 6 \(of 6\).
- cp /dev/null ark6isdone
- MISSING=""
- for I in 1 2 3 4 5 6 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 6 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
- --
- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
-
-
-